import java.util.Calendar;
import java.util.Date;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.UUID;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.List;

public class Main {
    private static BufferedReader reader;
    private static CinemaHall hall1 = new CinemaHall("1号厅", 10, 15);
    private static CinemaHall hall2 = new CinemaHall("2号厅", 8, 12);

    public static void main(String[] args) {
        try {
            // 初始化 BufferedReader
            reader = new BufferedReader(new InputStreamReader(System.in, "UTF-8"));
        } catch (UnsupportedEncodingException e) {
            System.err.println("不支持的字符编码: " + e.getMessage());
            return;
        }

        // 设置系统编码为UTF-8
        System.setProperty("file.encoding", "UTF-8");

        initializeSystem();

        while (true) {
            try {
                displayMainMenu();
                int choice = getUserChoice(1, 2);

                switch (choice) {
                    case 1:
                        login();
                        break;
                    case 2:
                        System.out.println("感谢使用影院管理系统，再见！");
                        return;
                }
            } catch (IOException e) {
                System.out.println("输入错误: " + e.getMessage());
            }
        }
    }

    private static void initializeSystem() {
        // 添加一些测试影片
        Manager testManager = new Manager(
                UUID.randomUUID().toString(),
                "manager",
                "manager123",
                new Date(),
                "13900000000"
        );

        testManager.addMovie("复仇者联盟4", "安东尼·罗素", "小罗伯特·唐尼,克里斯·埃文斯",
                "漫威电影宇宙的终结篇", 181, 8.5);
        testManager.addMovie("流浪地球2", "郭帆", "吴京,李雪健",
                "人类为了拯救地球而采取的一系列行动", 173, 8.3);

        // 添加一些测试场次
        Calendar calendar = Calendar.getInstance();

        calendar.set(2025, Calendar.JULY, 15, 19, 0);
        testManager.addShow(
                MovieManager.getMovieByName("复仇者联盟4"),
                hall1,
                calendar.getTime(),
                80.0
        );

        calendar.set(2025, Calendar.JULY, 15, 21, 30);
        testManager.addShow(
                MovieManager.getMovieByName("流浪地球2"),
                hall2,
                calendar.getTime(),
                75.0
        );
    }

    private static void displayMainMenu() {
        System.out.println("\n===== 影院管理系统 =====");
        System.out.println("1. 登录");
        System.out.println("2. 退出系统");
    }

    private static void login() throws IOException {
        System.out.print("请输入用户名: ");
        String username = reader.readLine();
        System.out.print("请输入密码: ");
        String password = reader.readLine();

        User user = UserManager.getUserByUsername(username);
        if (user == null) {
            System.out.println("用户不存在");
            return;
        }

        if (!user.login(password)) {
            System.out.println("密码错误");
            return;
        }

        System.out.println("登录成功，欢迎 " + user.getUsername() + " (" + user.getUserType() + ")");
        LogManager.recordLog("登录系统", new Date(), username);

        if (user instanceof Admin) {
            showAdminMenu((Admin) user);
        } else if (user instanceof Manager) {
            showManagerMenu((Manager) user);
        } else if (user instanceof Receptionist) {
            showReceptionistMenu((Receptionist) user);
        }
    }

    private static void showAdminMenu(Admin admin) {
        while (true) {
            try {
                System.out.println("\n===== 管理员菜单 =====");
                System.out.println("1. 添加用户");
                System.out.println("2. 删除用户");
                System.out.println("3. 列出所有用户");
                System.out.println("4. 修改密码");
                System.out.println("5. 查看个人信息");
                System.out.println("6. 退出登录");

                int choice = getUserChoice(1, 6);

                switch (choice) {
                    case 1:
                        addUser(admin);
                        break;
                    case 2:
                        deleteUser(admin);
                        break;
                    case 3:
                        admin.listAllUsers();
                        break;
                    case 4:
                        changePassword(admin);
                        break;
                    case 5:
                        admin.viewPersonalInfo();
                        break;
                    case 6:
                        admin.logout();
                        return;
                }
            } catch (IOException e) {
                System.out.println("输入错误: " + e.getMessage());
            } catch (Exception e) {
                System.out.println("操作出错: " + e.getMessage());
            }
        }
    }

    private static void showManagerMenu(Manager manager) {
        while (true) {
            try {
                System.out.println("\n===== 经理菜单 =====");
                System.out.println("1. 添加影片");
                System.out.println("2. 更新影片评分");
                System.out.println("3. 添加场次");
                System.out.println("4. 删除场次");
                System.out.println("5. 列出所有影片");
                System.out.println("6. 列出所有场次");
                System.out.println("7. 修改密码");
                System.out.println("8. 查看个人信息");
                System.out.println("9. 退出登录");

                int choice = getUserChoice(1, 9);

                switch (choice) {
                    case 1:
                        addMovie(manager);
                        break;
                    case 2:
                        updateMovieRating(manager);
                        break;
                    case 3:
                        addShow(manager);
                        break;
                    case 4:
                        deleteShow(manager);
                        break;
                    case 5:
                        listAllMovies();
                        break;
                    case 6:
                        listAllShows();
                        break;
                    case 7:
                        changePassword(manager);
                        break;
                    case 8:
                        manager.viewPersonalInfo();
                        break;
                    case 9:
                        manager.logout();
                        return;
                }
            } catch (IOException e) {
                System.out.println("输入错误: " + e.getMessage());
            } catch (Exception e) {
                System.out.println("操作出错: " + e.getMessage());
            }
        }
    }

    private static void showReceptionistMenu(Receptionist receptionist) {
        while (true) {
            try {
                System.out.println("\n===== 前台菜单 =====");
                System.out.println("1. 售票");
                System.out.println("2. 退票");
                System.out.println("3. 查看影片信息");
                System.out.println("4. 查看场次信息");
                System.out.println("5. 修改密码");
                System.out.println("6. 查看个人信息");
                System.out.println("7. 退出登录");

                int choice = getUserChoice(1, 7);

                switch (choice) {
                    case 1:
                        sellTicket(receptionist);
                        break;
                    case 2:
                        refundTicket(receptionist);
                        break;
                    case 3:
                        viewMovieInfo();
                        break;
                    case 4:
                        viewShowInfo(receptionist);
                        break;
                    case 5:
                        changePassword(receptionist);
                        break;
                    case 6:
                        receptionist.viewPersonalInfo();
                        break;
                    case 7:
                        receptionist.logout();
                        return;
                }
            } catch (IOException e) {
                System.out.println("输入错误: " + e.getMessage());
            } catch (Exception e) {
                System.out.println("操作出错: " + e.getMessage());
            }
        }
    }

    private static int getUserChoice(int min, int max) throws IOException {
        int choice;
        while (true) {
            try {
                String input = reader.readLine();
                choice = Integer.parseInt(input);
                if (choice >= min && choice <= max) {
                    break;
                } else {
                    System.out.printf("输入无效，请输入 %d 到 %d 之间的数字: ", min, max);
                }
            } catch (NumberFormatException e) {
                System.out.printf("输入无效，请输入 %d 到 %d 之间的数字: ", min, max);
            }
        }
        return choice;
    }

    private static void addUser(Admin admin) throws IOException {
        System.out.print("请输入用户类型 (ADMIN/MANAGER/RECEPTIONIST): ");
        String userType = reader.readLine();
        System.out.print("请输入用户名: ");
        String username = reader.readLine();
        System.out.print("请输入密码: ");
        String password = reader.readLine();
        System.out.print("请输入手机号: ");
        String phone = reader.readLine();

        User newUser;
        switch (userType) {
            case "ADMIN":
                newUser = new Admin(UUID.randomUUID().toString(), username, password, new Date(), phone);
                break;
            case "MANAGER":
                newUser = new Manager(UUID.randomUUID().toString(), username, password, new Date(), phone);
                break;
            case "RECEPTIONIST":
                newUser = new Receptionist(UUID.randomUUID().toString(), username, password, new Date(), phone);
                break;
            default:
                System.out.println("无效的用户类型");
                return;
        }

        admin.addUser(newUser);
        System.out.println("用户添加成功");
    }

    private static void deleteUser(Admin admin) throws IOException {
        System.out.print("请输入要删除的用户名: ");
        String username = reader.readLine();
        admin.deleteUser(username);
        System.out.println("用户删除成功");
    }

    private static void changePassword(User user) throws IOException {
        System.out.print("请输入原密码: ");
        String oldPwd = reader.readLine();
        System.out.print("请输入新密码: ");
        String newPwd = reader.readLine();
        try {
            user.changePassword(oldPwd, newPwd);
            System.out.println("密码修改成功");
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
    }

    private static void addMovie(Manager manager) throws IOException {
        System.out.print("请输入影片名称: ");
        String name = reader.readLine();
        System.out.print("请输入导演: ");
        String director = reader.readLine();
        System.out.print("请输入主演: ");
        String actors = reader.readLine();
        System.out.print("请输入简介: ");
        String introduction = reader.readLine();
        System.out.print("请输入时长 (分钟): ");
        int duration = Integer.parseInt(reader.readLine());
        System.out.print("请输入评分: ");
        double rating = Double.parseDouble(reader.readLine());

        manager.addMovie(name, director, actors, introduction, duration, rating);
        System.out.println("影片添加成功");
    }

    private static void updateMovieRating(Manager manager) throws IOException {
        System.out.print("请输入要更新评分的影片名称: ");
        String name = reader.readLine();
        System.out.print("请输入新的评分: ");
        double newRating = Double.parseDouble(reader.readLine());

        manager.updateMovieRating(name, newRating);
        System.out.println("影片评分更新成功");
    }

    private static void addShow(Manager manager) throws IOException {
        System.out.print("请输入影片名称: ");
        String movieName = reader.readLine();
        Movie movie = MovieManager.getMovieByName(movieName);
        if (movie == null) {
            System.out.println("影片不存在");
            return;
        }

        System.out.print("请输入放映厅名称 (1号厅/2号厅): ");
        String hallName = reader.readLine();
        CinemaHall hall;
        if ("1号厅".equals(hallName)) {
            hall = hall1;
        } else if ("2号厅".equals(hallName)) {
            hall = hall2;
        } else {
            System.out.println("无效的放映厅名称");
            return;
        }

        System.out.print("请输入放映时间 (格式: yyyy-MM-dd HH:mm): ");
        String showTimeStr = reader.readLine();
        try {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
            Date showTime = sdf.parse(showTimeStr);

            System.out.print("请输入票价: ");
            double price = Double.parseDouble(reader.readLine());

            manager.addShow(movie, hall, showTime, price);
            System.out.println("场次添加成功");
        } catch (ParseException e) {
            System.out.println("日期格式错误: " + e.getMessage());
        }
    }

    private static void deleteShow(Manager manager) throws IOException {
        System.out.print("请输入要删除的场次ID: ");
        String showId = reader.readLine();
        manager.deleteShow(showId);
        System.out.println("场次删除成功");
    }

    private static void listAllMovies() {
        System.out.println("所有影片列表:");
        List<Movie> movies = MovieManager.getAllMovies();
        if (movies.isEmpty()) {
            System.out.println("暂无影片信息");
        } else {
            for (Movie movie : movies) {
                movie.displayInfo();
                System.out.println("---------------------");
            }
        }
    }

    private static void listAllShows() {
        System.out.println("所有场次列表:");
        List<Show> shows = ShowManager.getAllShows();
        if (shows.isEmpty()) {
            System.out.println("暂无场次信息");
        } else {
            for (Show show : shows) {
                System.out.println("场次ID: " + show.getShowId());
                System.out.println("影片名称: " + show.getMovie().getName());
                System.out.println("放映时间: " + show.getShowTime());
                System.out.println("放映厅: " + show.getHall().getName());
                System.out.println("票价: " + show.getPrice());
                System.out.println("---------------------");
            }
        }
    }

    private static void sellTicket(Receptionist receptionist) throws IOException {
        System.out.print("请输入场次ID: ");
        String showId = reader.readLine();
        Show show = ShowManager.getShowById(showId);
        if (show == null) {
            System.out.println("场次不存在");
            return;
        }

        System.out.print("请输入要购买的座位数量: ");
        int seatCount = Integer.parseInt(reader.readLine());
        int[] rowNums = new int[seatCount];
        int[] colNums = new int[seatCount];

        for (int i = 0; i < seatCount; i++) {
            System.out.printf("请输入第 %d 个座位的排号: ", i + 1);
            rowNums[i] = Integer.parseInt(reader.readLine());
            System.out.printf("请输入第 %d 个座位的列号: ", i + 1);
            colNums[i] = Integer.parseInt(reader.readLine());
        }

        Ticket ticket = receptionist.sellTicket(show, rowNums, colNums);
        if (ticket != null) {
            System.out.println("售票成功");
            ticket.displayInfo();
        }
    }

    private static void refundTicket(Receptionist receptionist) throws IOException {
        System.out.print("请输入要退票的票号: ");
        String ticketId = reader.readLine();
        if (receptionist.refundTicket(ticketId)) {
            System.out.println("退票成功");
        }
    }

    private static void viewMovieInfo() throws IOException {
        System.out.print("请输入影片名称: ");
        String movieName = reader.readLine();
        Movie movie = MovieManager.getMovieByName(movieName);
        if (movie != null) {
            movie.displayInfo();
        } else {
            System.out.println("影片不存在");
        }
    }

    private static void viewShowInfo(Receptionist receptionist) throws IOException {
        System.out.print("请输入场次ID: ");
        String showId = reader.readLine();
        Show show = ShowManager.getShowById(showId);
        if (show != null) {
            receptionist.displayShowInfo(show);
        } else {
            System.out.println("场次不存在");
        }
    }
}